package demo.java.lang.enumeration;

import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.Enum;

/**
 * 枚举类,所有的枚举都继承自java.lang.Enum类
 */
public class EnumDemo {

    private static Logger logger = LoggerFactory.getLogger(EnumDemo.class);

    public void testEnum() {
        Enum a = Card.Rank.ACE;
    }

    /**
     * 因为枚举是有序的，所以可以获取指定范围
     */
    @Test
    public void range() {
        Set<Day> set = EnumSet.range(Day.Monday, Day.FRIDAY);
        for (Day d : set) {
            System.out.println(String.format("%s (%s) ordinal = %d", d.name(), d.toString(), d.ordinal()));
        }
    }

    /**
     * 因为枚举是有序的，所以可以获取指定范围
     */
    @Test
    public void demoSwitch() {
        Day d = Day.Monday;
        System.out.println(d);
        switch (d) {
            /*
             * 注意:枚举重写了ToString(),说以枚举变量的值是不带前缀的 所以为blue而非ColorSelect.blue
             */
            case SUNDAY:
                System.out.println("星期日");
                break;
            case SATURDAY:
                System.out.println("星期六");
                break;
            default:
                System.out.println("工作日");
        }
    }

    /**
     * <li>通过values()获得枚举值的数组
     * <li>ordinal()返回枚举值在枚举中的索引位置，从0开始
     */
    @Test
    public void demoValues() {
        System.out.println("遍历ENUM中的值");
        Day[] days = Day.values();
        for (Day day : days) {
            int ordinal = day.ordinal();
            logger.info("toString = {},ordinal = {}", day, ordinal);
        }
        System.out.println("枚举Day中的值有：" + days.length + "个");
    }

    /**
     * <li>通过values()获得枚举值的数组
     * <li>ordinal()返回枚举值在枚举中的索引位置，从0开始
     */
    @Test
    public void demoValueOf() {
        Day day = Enum.valueOf(Day.class, "SUNDAY");
        logger.info("{}", day);
        day = Day.valueOf("SUNDAY");
        logger.info("{}", day);
    }

    /**
     * <li>枚举默认实现了java.lang.Comparable接口
     */
    @Test
    public void demoComparable() {
        Day[] days = Day.values();
        for (Day day : days) {
            int result = day.compareTo(Day.WEDNESDAY);
            logger.info("{} compareTo {} ,return {}.", day, Day.WEDNESDAY, result);
        }
    }

    /**
     * 洗牌
     */
    @Test
    public void test() {
        int numHands = 2;
        int cardsPerHand = 5;
        List<Card> deck = Card.newDeck();
        Collections.shuffle(deck);
        for (int i = 0; i < numHands; i++) {
            System.out.println(Card.deal(deck, cardsPerHand));
        }
    }

    @Test
    public void demoPlanet() {
        System.out.println(Planet.EARTH.name());
        System.out.println(Planet.EARTH.toString());
        Planet[] planets = Planet.values();
        for (Planet planet : planets) {
            planet.print();
        }
        System.out.println(Planet.EARTH.mass());
        System.out.println(Planet.EARTH.radius());
        System.out.println(Planet.EARTH.surfaceWeight(75.0));
    }

    /**
     * 加减乘除
     */
    @Test
    public void demo3() {
        System.out.println(Operation2.PLUS.eval(7.0, 8.0));
        System.out.println(Operation2.MINUS.eval(7.0, 8.0));
        System.out.println(Operation2.TIMES.eval(7.0, 8.0));
        System.out.println(Operation2.DIVIDE.eval(7.0, 8.0));

        for (Operation2 op : Operation2.values()) {
            // java.util.Formatter a= null;
            System.out.printf("%f %s %f = %f%n", 7.0, op, 8.0, op.eval(7.0, 8.0));
        }
    }

    /**
     * 加减乘除
     */
    @Test
    public void demo4() {
        System.out.println(Operation1.PLUS.eval(7.0, 8.0));
        System.out.println(Operation1.MINUS.eval(7.0, 8.0));
        System.out.println(Operation1.TIMES.eval(7.0, 8.0));
        System.out.println(Operation1.DIVIDE.eval(7.0, 8.0));

        for (Operation1 op : Operation1.values()) {
            // java.util.Formatter a= null;
            System.out.printf("%f %s %f = %f%n", 7.0, op, 8.0, op.eval(7.0, 8.0));
        }
    }
}
